package com.yuchting.dinneronline.server;

import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

import org.json.JSONArray;
import org.json.JSONObject;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.yuchting.dinneronline.client.MainService;
import com.yuchting.dinneronline.share.ShareField;

public class MainServiceImpl extends RemoteServiceServlet implements MainService{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -1888600238614832215L;

	public static final class PMF {
		private static final PersistenceManagerFactory pmfInstance =
		        JDOHelper.getPersistenceManagerFactory("transactions-optional");

		private PMF() {}

	    public static PersistenceManagerFactory get() {
	        return pmfInstance;
	    } 
	}
	
	public String logonServer(String name,String password) throws Exception {
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
			
		try{
			User t_user = null;
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), name);
			try{
				t_user = t_pm.getObjectById(User.class, k);	
				
				if(!t_user.getPass().equals(password)){
					return "<Error>密码错误！</Error>";
				}
				
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				
				if(ShareField.isAdmin(name)){
					// auto add the administrator
					//
					t_user = new User();
					t_user.setName(name);
					t_user.setPass(password);
					
					t_pm.makePersistent(t_user);
					
				}else{
					return "<Error>找不到用户!</Error>";
				}
			}		
			
			return t_user.toJSON().toString();
			
		}finally{
			t_pm.close();
		}		
	}
	
	
	public String changePassword(String _name,String _orgPass,String _newPass)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			User t_user = null;
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), _name);
			try{
				t_user = t_pm.getObjectById(User.class, k);	
				
				if(!t_user.getPass().equals(_orgPass)){
					return "<Error>密码错误！</Error>";
				}
								
				t_user.setPass(_newPass);
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到用户!</Error>";
			}		
			
			return t_user.toJSON().toString();
			
		}finally{
			t_pm.close();
		}
	}
	
	public String getCurrOrderList(String _name)throws Exception{
		return getOrderListImpl(_name,System.currentTimeMillis());
			
	}
	
	public String getFormerOrderList(String _name)throws Exception{
		return getOrderListImpl(_name,System.currentTimeMillis() - Config.fsm_oneDayMillisecond);
	}
	
	private String getOrderListImpl(String _name,long _time)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{					
			
			Config.ConfigSegmentTime t_seg = getConfigImpl(t_pm).getSegTime(_time);
			
			List<Order> t_orderList = (List<Order>)t_pm.newQuery("select from " + Order.class.getName() + 
											" where m_username==" + "\"" + _name + "\" && m_time>=" + t_seg.formerEnd +
											" && m_time<" + t_seg.currStart).execute();
						
			JSONArray t_list = new JSONArray();
			for(Order order:t_orderList){
				t_list.put(order.toJSON());
			}
			
			return t_list.toString();
			
		}finally{
			t_pm.close();
		}	
	}
		
	public String getCurrDinnerList()throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{

			List<Dinner> t_dinnerList = (List<Dinner>)t_pm.newQuery("select from " + Dinner.class.getName()).execute();
						
			JSONArray t_list = new JSONArray();
			for(Dinner dinner:t_dinnerList){
				t_list.put(dinner.toJSON());
			}
			
			return t_list.toString();
			
		}finally{
			t_pm.close();
		}	
	}
	
	public String delOrder(String _username,long _orderTime)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			if(getConfigImpl(t_pm).isOrderOutTime(System.currentTimeMillis())){
				return "<Error>此时是出单时间，无法取消定单了！</Error>";
			}
			
			User t_user = null;
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), _username);
			try{
				t_user = t_pm.getObjectById(User.class, k);
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到用户!</Error>";
			}

			List<Order> t_orderList = (List<Order>)t_pm.newQuery("select from " + Order.class.getName() + 
													" where m_username==" + "\"" + _username + "\" && m_time==" + _orderTime).execute();
			StringBuffer t_ret = new StringBuffer();
			
			if(!t_orderList.isEmpty()){
				
				Dinner t_dinner = null;
				
				for(Order order:t_orderList){
					
					t_ret.append(order.getTime()).append(";");
					
					// decrase the dinner order number
					//
					
					k = KeyFactory.createKey(Dinner.class.getSimpleName(), order.getDinnerName());
					try{
						t_dinner = t_pm.getObjectById(Dinner.class, k);
						t_dinner.setOrderNum(t_dinner.getOrderNum() - 1);	
						
						t_pm.makePersistent(t_dinner);
						
					}catch(Exception e){
						e.printStackTrace();
					}
					
					// give back money
					//
					t_user.setRemainMoney(t_user.getRemainMoney() + order.getPayMoney());
					t_user.setTotalPay(t_user.getTotalPay() - order.getPayMoney());
					
					t_pm.deletePersistent(order);				
				}
			}			
			
			return t_ret.toString();
			
		}finally{
			t_pm.close();
		}
	}
	
	public String addOrder(String _username,String _dinner)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			if(getConfigImpl(t_pm).isOrderOutTime(System.currentTimeMillis())){
				return "<Error>此时是出单时间，无法再下单了！</Error>";
			}
				
			User t_user = null;
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), _username);
			try{
				t_user = t_pm.getObjectById(User.class, k);
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到用户!</Error>";
			}
			
			Dinner t_dinner = null;
			k = KeyFactory.createKey(Dinner.class.getSimpleName(), _dinner);
			try{
				t_dinner = t_pm.getObjectById(Dinner.class, k);
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到菜!</Error>";
			}
			
			if(t_user.getRemainMoney() < t_dinner.getPrice()){
				return "<Error>钱不够了，找管理员充值吧！</Error>";
			}
			
			// increase the order number
			//
			t_dinner.setOrderNum(t_dinner.getOrderNum() + 1);
			t_pm.makePersistent(t_dinner);
			
			// make order 
			//
			Order t_order = new Order(t_user,t_dinner);
			t_pm.makePersistent(t_order);
			
			t_user.setRemainMoney(t_user.getRemainMoney() - t_dinner.getPrice());
			t_user.setTotalPay(t_user.getTotalPay() + t_dinner.getPrice());
			
			return t_order.toJSON().toString();
			
		}finally{
			t_pm.close();
		}
	}
	
	public static Config getConfigImpl(PersistenceManager _pm)throws Exception{
		
		Config t_result = null;
		
		try{
			t_result = (Config)MainServiceCache.queryCache().get(Config.class.getName());
		}catch(Exception e){
			e.printStackTrace(System.err);
		}
		
		if(t_result == null){
			
			Key k = KeyFactory.createKey(Config.class.getSimpleName(), Config.class.getName());
			try{
				t_result = _pm.getObjectById(Config.class, k);	
								
			}catch(javax.jdo.JDOObjectNotFoundException e){	
				t_result = new Config();
				
				_pm.makePersistent(t_result);
				
			}
			
			try{
				MainServiceCache.queryCache().put(Config.class.getName(), t_result);
			}catch(Exception e){
				e.printStackTrace(System.err);
			}			
		}
		
		return t_result;			
	}
	
	public String getConfig()throws Exception{
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			return getConfigImpl(t_pm).toJSON().toString();			
		}finally{
			t_pm.close();
		}
	}
	
	public String setConfig(String _configJSON)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Config t_config = getConfigImpl(t_pm);
			t_config.fromJSON(new JSONObject(_configJSON));
			
			// change the persistent of store
			t_pm.makePersistent(t_config);
			
			// remove the memcache of config
			MainServiceCache.queryCache().remove(Config.class.getName());
			
			return "设置成功！";
			
		}finally{
			t_pm.close();
		}
	}
	
	public String delDinner(String _name)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Dinner t_dinner = null;
			Key k = KeyFactory.createKey(Dinner.class.getSimpleName(), _name);
			try{
				t_dinner = t_pm.getObjectById(Dinner.class, k);
				
				t_pm.deletePersistent(t_dinner);
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到菜!</Error>";
			}
			
			return "<OK />";
			
		}finally{
			t_pm.close();
		}
	}
	
	public String addDinner(String _dinnerJSON)throws Exception{
		
		Dinner t_newDinner = new Dinner();
		t_newDinner.fromJSON(new JSONObject(_dinnerJSON));
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Key k = KeyFactory.createKey(Dinner.class.getSimpleName(), t_newDinner.getName());
			try{
				t_pm.getObjectById(Dinner.class, k);
				
				return "<Error>" + t_newDinner.getName() + " 已经存在</Error>";
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				t_pm.makePersistent(t_newDinner);				
			}
			
			return "<OK />";
			
		}finally{
			t_pm.close();
		}
	}
	
	public String modifyDinner(String _name,String _dinnerJSON)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Dinner t_dinner = null;
			Key k = KeyFactory.createKey(Dinner.class.getSimpleName(), _name);
			try{
				t_dinner = t_pm.getObjectById(Dinner.class, k);
				t_dinner.fromJSON(new JSONObject(_dinnerJSON));
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到!</Error>";
			}
			
			return "<OK />";
			
		}finally{
			t_pm.close();
		}
	}
	
	public String getCurrUserList()throws Exception{
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			List<User> t_userList = (List<User>)t_pm.newQuery("select from " + User.class.getName()).execute();
			JSONArray t_array = new JSONArray();
			for(User u:t_userList){
				t_array.put(u.toJSON());
			}
			
			return t_array.toString();
			
		}finally{
			t_pm.close();
		}
	}
	public String delUser(String _username)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), _username);
			try{
				User t_user = t_pm.getObjectById(User.class, k);
				
				t_pm.deletePersistent(t_user);
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到!</Error>";
			}
			
			return "<OK />";
			
		}finally{
			t_pm.close();
		}
		
	}
	public String addUser(String _userJSON)throws Exception{
		
		User t_user = new User();
		t_user.fromJSON(new JSONObject(_userJSON));
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), t_user.getName());
			try{
				t_pm.getObjectById(User.class, k);
				
				return "<Error>" + t_user.getName() + " 已经存在</Error>";
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				t_pm.makePersistent(t_user);
			}
			
			return _userJSON;
			
		}finally{
			t_pm.close();
		}
	}
	
	public String modifyUser(String _userJSON)throws Exception{
		
		JSONObject t_obj = new JSONObject(_userJSON);
		
		User t_user = new User();
		t_user.fromJSON(t_obj);
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			Key k = KeyFactory.createKey(User.class.getSimpleName(), t_user.getName());
			try{
				
				t_user = t_pm.getObjectById(User.class, k);
				t_user.fromJSON(t_obj);
				
			}catch(javax.jdo.JDOObjectNotFoundException e){
				return "<Error>找不到用户</Error>";
			}
			
			return _userJSON;
			
		}finally{
			t_pm.close();
		}
	}
	
	public String getCurrOrderOutList()throws Exception{
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{					
			
			Config.ConfigSegmentTime t_seg = getConfigImpl(t_pm).getSegTime(System.currentTimeMillis());
			
			List<Order> t_orderList = (List<Order>)t_pm.newQuery("select from " + Order.class.getName() + 
											" where m_time>=" + t_seg.formerEnd +
											" && m_time<" + t_seg.currStart).execute();			
						
			JSONArray t_list = new JSONArray();
			for(Order order:t_orderList){
				t_list.put(order.toJSON());
			}
			
			return t_list.toString();
			
		}finally{
			t_pm.close();
		}
	}
	
	public String checkOrderOutList(long _time)throws Exception{
		
		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{					
			
			Config.ConfigSegmentTime t_seg = getConfigImpl(t_pm).getSegTime(_time);
			
			List<Order> t_orderList = (List<Order>)t_pm.newQuery("select from " + Order.class.getName() + 
											" where m_time>=" + t_seg.formerEnd +
											" && m_time<" + t_seg.currStart).execute();
									
			JSONArray t_list = new JSONArray();
			for(Order order:t_orderList){
				t_list.put(order.toJSON());
			}
			
			return t_list.toString();
			
		}finally{
			t_pm.close();
		}
	}
	
	public String commentOrder(String _user,String _commnet,byte[] _rank,long _orderTime)throws Exception{

		PersistenceManager t_pm = PMF.get().getPersistenceManager();
		
		try{
			
			List<Order> t_orderList = (List<Order>)t_pm.newQuery("select from " + Order.class.getName() + 
					" where m_time==" + _orderTime + " && m_username==\"" + _user + "\"").execute();
			
			if(t_orderList.isEmpty()){
				return "<Error>找不到订单!</Error>";
			}
			
			Dinner t_dinner = null;
			for(Order o:t_orderList){
				
				Key k = KeyFactory.createKey(Dinner.class.getSimpleName(), o.getDinnerName());
				try{
					t_dinner = t_pm.getObjectById(Dinner.class, k);				
					t_dinner.calcCurrRank(_rank);
					
					t_pm.makePersistent(t_dinner);
										
				}catch(javax.jdo.JDOObjectNotFoundException e){
					return "<Error>找不到菜!</Error>";
				}
				

				Comment c = new Comment(t_dinner.getName(),_orderTime,_user,_commnet,_rank);
				t_pm.makePersistent(c);
			}
			
			return Long.toString(_orderTime);
			
		}finally{
			t_pm.close();
		}
	}
	
}
